#include <stdio.h>
#include <string.h>
#include <conio.h>
#include <Windows.h>
// #include "resource.h"

#define H 10

struct tel
{
	char *nrtel;
	tel *next;
};

struct nod
{
	char *Nume;
	char *Prenume;
	tel *head;
	nod *next;
};
typedef nod *HT[H];

int hash( char *sir)
{
	int i,sum=0;
	for(i=0;i<strlen(sir);i++)
		sum+=sir[i];
	return sum%10;
}

void init_hash(HT M)
{
	int i;
	for(i=0;i<H;i++)
		M[i]=0;

}

nod *add_list(char *nume, char *prenume, char *nrtel)
{
	nod *nou=(nod*)malloc(sizeof(nod));
	nou->Nume = (char*)malloc(strlen(nume)*sizeof(char));
	nou->Prenume = (char*)malloc(strlen(prenume)*sizeof(char));
	nou->head = new tel;
	nou->head->nrtel = ( char *)malloc(strlen(nrtel)*sizeof(char));
	nou->head->next=NULL;
	strcpy(nou->Nume,nume);
	strcpy(nou->Prenume,prenume);
	strcpy(nou->head->nrtel,nrtel);
	nou->next=NULL;
	return nou;
}

void add_contact(HT M,char *nume, char *prenume, char *nrtel)
{
	int k=hash(nume);
	nod *poz= M[k];
	if ( poz == NULL)
	{
		nod *crt=add_list(nume,prenume,nrtel);
		M[k]=crt;
		return;
	}
	else
	{
		nod *crt=add_list(nume,prenume,nrtel);
		crt->next=M[k];
		M[k]=crt;
		return;
	}
}
void show_hash(HT M)
{
	int i;
	for (i=0;i<H;i++)
	{
		nod *crt=M[i];	
		if(crt!=NULL)
		{
			printf("\n %d",i);
			while(crt!=NULL)
			{
				printf("\t %s %s",crt->Nume,crt->Prenume);
				tel *crt1=crt->head;
				while( crt1 != NULL)
				{
					printf(" %s",crt1->nrtel);
					crt1=crt1->next;
				}
				crt=crt->next;
			}
		}

	}
	
}

nod *find_contact(HT M, char *nume, char *prenume)
{
	int k=hash(nume);
	nod *crt = M[k];
	if( crt == NULL)
	{
		printf("\n Nu s-a putut gasi persoana.");
		return NULL;
	}
	while ( crt != NULL)
	{
		if( strcmp(crt->Nume,nume) == 0 && strcmp(crt->Prenume,prenume) == 0 )
		{
			printf("\n S-a gasit persoana .");
			return crt;
		}
		crt=crt->next;
	}
}

void erase_contact(HT M,char *nume, char *prenume)
{
	int k=hash(nume);
	nod *gasit=find_contact(M,nume,prenume);
	if( M[k]->next ==NULL && gasit ->next == NULL)
	{
		nod *aux=gasit;
		gasit=gasit->next;
		M[k]=NULL;
		free(aux);
		printf("\n Stergerea s-a efectuat cu succes.");
		return;
	}
	else
	{
		nod *crt=M[k];
		int nr=0;
		if( crt == gasit )
		{
			//capul listei
			M[k]=crt->next;
			free(crt);
			printf("\n Stergerea s-a efectuat cu succes.");
			return;
		}
		while(crt->next != gasit)
			crt=crt->next;
		//retin de pointerul anterior
		crt->next=gasit->next;
		free(gasit);
		printf("\n Stergerea s-a realizat cu succes.");
		return;
		
	}
}

void free_hash(HT M)
{
	//eliberez toata memoria;
	for(int i=0;i<H;i++)
	{
		//ptr fiecare contact si ptr fiecare numar de telefon
		nod *crt=M[i];
		while(crt != NULL)
		{
			tel *crt1=crt->head;
			while ( crt1->next != NULL)
			{
				tel *aux=crt1;
				crt1=crt1->next;
				free(aux);
			}
			nod *Aux1=crt;
			crt=crt->next;
			free(Aux1);
			

		}
	}
	init_hash(M);

}

void add_tel(HT M,char *nume, char *prenume, char *nrtel)
{
	int k=hash(nume);
	nod *gasit=find_contact(M,nume,prenume);
	if( gasit != NULL)
	{
		tel *aux=gasit->head;
		while(aux->next != NULL)
			aux=aux->next;
		tel *nou=new tel;
		nou->nrtel = (char *) malloc(strlen(nrtel)*sizeof(char));
		strcpy(nou->nrtel,nrtel);
		nou->next=NULL;
		aux->next=nou;
		return;
	}
}

void menu()
{
		printf("\n\n\n");
		printf("\n\t 1. Initializare NULL agenda telefonica.");
		printf("\n\t 2. Introducere persoana noua in agenda telefonica.");
		printf("\n\t 3. Stergere persoana agenda telefonica.");
		printf("\n\t 4. Cautare persoana in agenda telefonica.");
		printf("\n\t 5. Afisare agenda!");
		printf("\n\t 6. Adauga nr tel persoana existenta in agenda telefonica.");
		printf("\n\t 7. Elibereaza memoria.");
		printf("\n\t 0. Iesire.");
}

int main()
{
	HT M;
	init_hash(M);
	char nume[10],prenume[10],nrtel[10];
	int ok=1;
	do
	{		
		menu();
		ok=1;
		printf("\n\n Introduceti optiunea dorita :");
		fflush(stdin);
		int ch = getch();
		switch ( ch )
		{
			case '1':
				{
					system("cls");
					init_hash(M);
					printf("\n Initializarea agendei a avut loc cu succes.");
					ok=1;
					break;			
				}
			case '2': 
				{
					system("cls");
					printf("\n Introduceti numele,prenumele,nr de telefon, orasul persoanei : ");
					scanf("%s",nume);
					scanf("%s",prenume);
					scanf("%s",nrtel);
					add_contact(M,nume,prenume,nrtel);
					printf("\n Inserarea s-a realizat cu succes.");
					ok=1;
					break;
				}
			case '3':
				{
					system("cls");
					printf("\n Introduceti numele si prenumele persoanei pe care doriti sa o stergeti din agenda telefonica .");
					scanf("%s",nume);
					scanf("%s",prenume);
					erase_contact(M,nume,prenume);
					ok=1;
					break;

				}
			case '4':
				{
					system("cls");
					printf("\n Va rugam introduceti Numele si Prenumele persoanei cautate : ");
					printf("\n Nume ");
					scanf("%s",nume);
					scanf("%s",prenume);
					find_contact(M,nume,prenume);
					ok=1;
					break;
				}
			case '5':
				{
					printf("\n Agenda telefonica este:");
					show_hash(M);
					ok=1;
					break;

				}
	
			case '6':
				{

					printf("\n Introduceti numele si prenumele persoanei si noul nr de telefon :");
					scanf("%s",nume);
					scanf("%s",prenume);
					scanf("%s",nrtel);
					add_tel(M,nume,prenume,nrtel);
					ok=1;
					break;
				}
			case '7':
				{
					free_hash(M);
					printf("\n Memoria s-a eliberat cu succes.");
					ok=0;
					break;
				}
			case '0':
				{
					printf("\n La revedere !");					
					ok=0;
				}
		}
		
	}while(ok);
	getch();
	return 0;
}